package pers.dawnyang.config.shiro;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import pers.dawnyang.common.constant.Const;
import pers.dawnyang.common.util.math.RandomUtil;
import pers.dawnyang.modular.system.domain.common.PermsInfo;
import pers.dawnyang.modular.system.domain.common.RoleInfo;
import pers.dawnyang.modular.system.domain.common.UserInfo;
import pers.dawnyang.modular.system.service.SystemService;

/**
 * 
 * @author dawn
 * @date 2021/04/20
 */
public class ShiroUserRealm extends AuthorizingRealm {

  @Autowired
  private SessionDAO sessionDao;

  @Autowired
  private SystemService systemService;

  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection auth) {
    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    String userCode = (String) auth.getPrimaryPrincipal();
    UserInfo userInfo = systemService.getUserInfo(userCode);
    List<RoleInfo> roleList = userInfo.getRoleList();
    List<String> permissionList = new ArrayList<>();
    for (RoleInfo roleInfo : roleList) {
      List<PermsInfo> permsList = roleInfo.getPermsList();
      for (PermsInfo permsInfo : permsList) {
        permissionList.add(permsInfo.getPerms());
      }
    }
    // simpleAuthorizationInfo.addRoles(roleList);
    simpleAuthorizationInfo.addStringPermissions(permissionList);
    return simpleAuthorizationInfo;
  }

  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth)
      throws AuthenticationException {
    String userCode = (String) auth.getPrincipal();

    /* 限制同一用户多浏览器同时登陆 */
    Collection<Session> sessions = sessionDao.getActiveSessions();
    for (Session session : sessions) {
      String loginedUserCode =
          String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY));
      if (userCode.equals(loginedUserCode)) {
        session.setTimeout(0);
        sessionDao.delete(session);
        break;
      }
    }

    UserInfo user = systemService.getUserInfo(userCode);
    if (user != null) {
      SimpleAuthenticationInfo authInfo = new SimpleAuthenticationInfo(userCode, user.getPassword(),
          ByteSource.Util.bytes(user.getSalt()), getName());
      return authInfo;
    }
    return null;
  }

  public static void main(String[] args) {
    String salt = RandomUtil.getRandomString(Const.SALT_FIGURE);
    Md5Hash md5Hash = new Md5Hash("111111", salt, Const.MD5_NUM);
    System.out.println("pwd:" + md5Hash);
    System.out.println("salt:" + salt);
  }
}
